package com.example.common.utils;

import com.alibaba.fastjson.JSONObject;
import com.aliyun.auth.credentials.Credential;
import com.aliyun.auth.credentials.provider.StaticCredentialProvider;
import com.aliyun.sdk.service.dysmsapi20170525.AsyncClient;
import com.aliyun.sdk.service.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.sdk.service.dysmsapi20170525.models.SendSmsResponse;
import com.example.sys.entity.Menus;
import com.google.gson.Gson;
import darabonba.core.client.ClientOverrideConfiguration;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

@Slf4j
public class Util {

    private static final String ACCESS_KEY_ID = "LTAI5tCWSP1zewhkEmHQ15xh";
    private static final String ACCESS_KEY_SECRET = "KsT3VgXRmVGrd1Ih3Gl4T941OqfUjX";
    private static final String SIGN_NAME = "点餐小程序";
    private static final String TEMPLATE_CODE = "SMS_461890272";

    public static final String[] TYPE_NAME = {"X", "Z", "D", "B"};

    @Resource
    private static RedisTemplate<String, String> redisTemplate = SpringBeanUtils.redisString;

    /**
     * 菜单格式
     * @param menus 数据集
     * @return
     */
    public static List<Menus> formatMenus(List<Menus> menus) {
        List<Menus> parents = new ArrayList<>();
        menus.forEach(c -> {
            if(0 == c.getParent()) {
                parents.add(c);
            }
        });
        parents.forEach(a -> {
            List<Menus> children = new ArrayList<>();
            menus.forEach(c -> {
                if(c.getParent() == a.getId()) {
                    children.add(c);
                }
            });
            a.setChildren(children);
        });
        return parents;
    }

    /**
     * generateLettersAndNumbers 无参方法 (默认值)
     * @return
     */
    public static String generateLettersAndNumbers() {
        return generateLettersAndNumbers(10);
    }

    /**
     * 随机生成含大小写及数字的字符串
     * @param bound 字符串长度
     * @return
     */
    public static String generateLettersAndNumbers(int bound) {
        Random random = new Random();
        String str = "";
        for (int i = 0; i < bound; i++) {
            int type = random.nextInt(3); // 随机生成字符的类型：0表示小写字母，1表示大写字母，2表示数字
            char c;
            switch (type) {
                case 0:
                    c = (char) (random.nextInt(26) + 'a');
                    break;
                case 1:
                    c = (char) (random.nextInt(26) + 'A');
                    break;
                default:
                    c = (char) (random.nextInt(10) + '0');
                    break;
            }
            str += c;
        }
        return str;
    }

    /**
     * 发送短信
     * @param phone 手机号
     * @return
     */
    public static boolean sendCode(String phone) {
        int code = new Random().nextInt(899999) + 100000;
        StaticCredentialProvider provider = StaticCredentialProvider.create(Credential
                .builder()
                .accessKeyId(ACCESS_KEY_ID)
                .accessKeySecret(ACCESS_KEY_SECRET)
                .build());
        AsyncClient client = AsyncClient.builder()
                .region("cn-hangzhou")
                .credentialsProvider(provider)
                .overrideConfiguration(
                        ClientOverrideConfiguration.create()
                                .setEndpointOverride("dysmsapi.aliyuncs.com")
                )
                .build();
        String codeStr = "{\"code\":" + code + "}";
        try {
            SendSmsRequest sendSmsRequest = SendSmsRequest
                    .builder()
                    .phoneNumbers(phone)
                    .signName(SIGN_NAME)
                    .templateCode(TEMPLATE_CODE)
                    .templateParam(codeStr)
                    .build();
            CompletableFuture<SendSmsResponse> sendSms = client.sendSms(sendSmsRequest);
            SendSmsResponse response = sendSms.get();
            String json = new Gson().toJson(response);
            JSONObject jsonObject = JSONObject.parseObject(json);
            String body = jsonObject.get("body").toString();
            String rsCode = JSONObject.parseObject(body).get("code").toString();
            log.info("短信发送结果：{}", body);
            if("OK".equals(rsCode)) {
                redisTemplate.opsForValue().set(phone, Integer.toString(code), 2, TimeUnit.MINUTES);
                return true;
            }else {
                return false;
            }
        }catch (Exception e) {
            log.error("短信发送失败：{}", e);
            return false;
        }
    }

    /**
     * 处理解密数据
     * @param params 参数字符串
     * @return
     */
    public static Map<String, String> transformParams(String params) {
        return Util.transformParams(params, Map.class);
    }

    /**
     * 处理解密数据
     * @param params 参数字符串
     * @param clazz 转换数据类型
     * @return
     */
    public static <T> T transformParams(String params, Class<T> clazz) {
        return JSONObject.parseObject(params, clazz);
    }

    /**
     * 生成唯一ID
     * @param bound 字符长度
     * @return  生成结果
     */
    public static String generateUID(int bound) {
        String hashCode = (Math.abs(UUID.randomUUID().hashCode()) + "");
        String suffix = hashCode;
        String prefix = (System.nanoTime() + "").substring(0, bound - hashCode.length());
        return prefix + suffix;
    }
}
